package com.iflytek.uoamp.notify.core.handler;

import static io.netty.handler.codec.http.HttpMethod.GET;
import static io.netty.handler.codec.http.HttpMethod.POST;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.iflytek.uoamp.common.notify.util.DESUtils;
import com.iflytek.uoamp.common.notify.util.LogbackInstance;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.util.CharsetUtil;

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
	
	private static final Logger logger = LogbackInstance.getInstance().getLogger(HttpRequestHandler.class);
	
	private static final HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE);
	
	private static final String PRIVATE_KEY = "1FLYTEK-0831";
	
	private static final String PAGECONTENT = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /><title>"
	        + "Test Page For Notify</title></head><body><form action=\"test.do\" method=\"POST\"><table><tr><th><p>POST数据:</p></th><td><textarea "
	        + "cols=\"60\" rows=\"20\" name=\"data\"></textarea></td></tr><tr><td align=\"right\"><input type=\"submit\" value=\"提交\"></td>"
	        + "<td align=\"left\"><input type=\"reset\"></td></tr></table></form></body></html>";
	
	private HttpPostRequestDecoder decoder = null;
	
	private boolean isDES = true;

	/**
	 * 处理Get请求，这里返回的是测试页；
	 * 
	 * @param ctx
	 * @param request
	 */
	private HttpResponse parseGet(ChannelHandlerContext ctx, HttpRequest request) {
		HttpResponse response = null;
		String html = null;

		if ("/".equals(request.getUri())) {
			html = PAGECONTENT;
		}
		
		if (html != null && !html.isEmpty()) {
			response = ResponseHelper.getResponse(ctx, html);
		} else {
			response = ResponseHelper.getResponse(ctx, "请求失败!");
		}

		return response;
	}

	/**
	 * 处理Post请求，会标记是否需要解密
	 * 
	 * @param ctx
	 * @param request
	 * @return
	 */
	private boolean parsePost(ChannelHandlerContext ctx, HttpRequest request) {
		
		if ("/test.do".equals(request.getUri())) {
			decoder = new HttpPostRequestDecoder(factory, request);
			isDES = false;
		} else if ("/notify.do".equals(request.getUri())) {
		    return true;
		} else {
			return false;
		}

		return true;
	}

	/**
	 * 处理正文内容，将byte[]转换为字符串
	 * @param ctx
	 * @param content
	 * @return
	 * @throws Exception；遇到异常则终止本次请求
	 */
	private boolean parseRequestContent(ChannelHandlerContext ctx, HttpContent content) throws Exception{
	    String desMsg = null;
	    if(!isDES){
		    if(decoder==null){
	            return false;
	        }
	        decoder.offer(content);
	        if (!decoder.hasNext()) {
	            return false;
	        }
	        
	        InterfaceHttpData data = decoder.next();
	        if (data.getHttpDataType() != HttpDataType.Attribute) {
	            return false;
	        }
	        Attribute attribute = (Attribute) data;
	        desMsg = new String(attribute.get(),"utf-8");
		}else{
		    ByteBuf buf = content.content();
		    byte[] cc = new byte[buf.readableBytes()];
		    buf.readBytes(cc);
		    byte[] plainBytes = DESUtils.decrypt(cc, PRIVATE_KEY.getBytes(CharsetUtil.UTF_8)); 
		    desMsg = new String(plainBytes,"utf-8");
		}

	    if(!StringUtils.isBlank(desMsg)) {
	        ctx.fireChannelRead(desMsg);
	    } else {
	        return false;
	    }

		return true;
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
		HttpResponse response = null;
        try {
            HttpRequest request = (HttpRequest) msg;

            if (request.getMethod() == GET) { // GET请求返回提交数据页面
                response = parseGet(ctx, request);
            } else if (request.getMethod() == POST) { // POST请求用于处理告警报文
                if (!parsePost(ctx, request)) {
                    response = ResponseHelper.getResponse(ctx, "POST请求提交失败!");
                } else if (!parseRequestContent(ctx, (LastHttpContent) msg)) {
                    response = ResponseHelper.getResponse(ctx, "获取POST数据失败!");
                }
            }

            if (response != null) {
                ResponseHelper.send(ctx, response);
            }
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			ResponseHelper.send(ctx, ResponseHelper.getResponse(ctx, "请求提交失败!"));
		}
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		ctx.flush();
	}

	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		if (decoder != null) {
			decoder.cleanFiles();
		}
	}
}
